{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/sugarforever/LangChain-Advanced/blob/main/Integrations/AutoGen/autogen_langchain_uniswap_ai_agent.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# AutoGen + LangChain Use Case - Uniswap Protocol AI Agent\n",
        "\n",
        "**`AutoGen`** is a versatile framework that facilitates the creation of LLM applications by employing multiple agents capable of interacting with one another to tackle tasks. These AutoGen agents can be tailored to specific needs, engage in conversations, and seamlessly integrate human participation. They are adaptable to different operation modes that encompass the utilization of LLMs, human inputs, and various tools.\n",
        "\n",
        "**`LangChain`** is an open-source framework designed for software developers engaged in AI and ML. It enables them to seamlessly integrate LLM with external components, facilitating the creation of LLM-driven applications. The primary aim of LangChain is to establish connections between LLMs such as OpenAI's GPT-3.5 and GPT-4 and various external data sources, enabling the development and utilization of NLP applications.\n",
        "\n",
        "Both of them are playing key roles in the LLM application development.\n",
        "\n",
        "`AutoGen` doesn't support connecting to various external data sources natively. This is exactly where `LangChain` can come into play."
      ],
      "metadata": {
        "id": "39_S0tWcB-oh"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Use Case - Uniswap Protocol\n",
        "\n",
        "`Uniswap` is a decentralized exchange that allows users to trade Ethereum-based tokens.\n",
        "\n",
        "In this tutorial, I will walk you through the steps to follow to build an AI agent that can complete tasks that involve Uniswap knowledge.\n",
        "\n",
        "1. Build up a vector store with Uniswap V3 whitepaper.\n",
        "2. Set up a conversational retrieval QA chain by LangChain, based on the vector store.\n",
        "3. Define a function `answer_uniswap_question` by taking a parameter `question`, calling the QA chain to answer it.\n",
        "4. Set up AutoGen user agent and assistant agent with function calling enabled.\n",
        "\n",
        "  - In the function mapping, the function defined in step 3 is included.\n",
        "  - The assistant agent is instructed by the following message to call the function `answer_uniswap_question` to answer Uniswap related questions.\n",
        "\n",
        "    ```\n",
        "    I'm writing a blog to introduce the version 3 of Uniswap protocol. Find the answers to the 3 questions below and write an introduction based on them.\n",
        "\n",
        "    1. What is Uniswap?\n",
        "    2. What are the main changes in Uniswap version 3?\n",
        "    3. How to use Uniswap?\n",
        "\n",
        "    Start the work now.\n",
        "    ```\n",
        "\n",
        "  - The function call is done by user agent."
      ],
      "metadata": {
        "id": "NtvjgnBZZjUL"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Environment Preparation"
      ],
      "metadata": {
        "id": "z73o7bmtb5LH"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "execution": {
          "iopub.execute_input": "2023-02-13T23:40:52.317406Z",
          "iopub.status.busy": "2023-02-13T23:40:52.316561Z",
          "iopub.status.idle": "2023-02-13T23:40:52.321193Z",
          "shell.execute_reply": "2023-02-13T23:40:52.320628Z"
        },
        "id": "1VRZnGGGgkhl"
      },
      "outputs": [],
      "source": [
        "%pip install pyautogen~=0.1.0 docker langchain openai tiktoken chromadb pypdf -q -U"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!wget -O uniswap_v3.pdf https://uniswap.org/whitepaper-v3.pdf"
      ],
      "metadata": {
        "id": "YL7GbhDnSOFE"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import autogen\n",
        "\n",
        "config_list = autogen.config_list_from_json(\n",
        "    \"OAI_CONFIG_LIST\",\n",
        "    filter_dict={\n",
        "        \"model\": [\"gpt-4\"],\n",
        "    },\n",
        ")\n",
        "#\n",
        "# Sample content of OAI_CONFIG_LIST file below:\n",
        "#\n",
        "# [\n",
        "#   {\n",
        "#     \"model\": \"gpt-4\",\n",
        "#     \"api_key\": \"your openai api key\"\n",
        "#   }\n",
        "# ]\n",
        "#"
      ],
      "metadata": {
        "id": "HZ7w_A3nXU8-"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "gpt4_api_key = config_list[0][\"api_key\"]"
      ],
      "metadata": {
        "id": "EFD1i82uXYhI"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "os.environ['OPENAI_API_KEY'] = gpt4_api_key"
      ],
      "metadata": {
        "id": "ZhfDAOAeSUJg"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain.vectorstores import Chroma\n",
        "from langchain.embeddings import OpenAIEmbeddings\n",
        "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
        "from langchain.document_loaders import PyPDFLoader\n",
        "from langchain.memory import ConversationBufferMemory\n",
        "from langchain.llms import OpenAI\n",
        "from langchain.chains import ConversationalRetrievalChain"
      ],
      "metadata": {
        "id": "1WVvbWIDSWMR"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Steps"
      ],
      "metadata": {
        "id": "BA48TH6Hc_3c"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "#### 1. Build up a vector store with Uniswap V3 whitepaper."
      ],
      "metadata": {
        "id": "rCrCnRC7cdC-"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "loaders = [ PyPDFLoader('./uniswap_v3.pdf') ]\n",
        "docs = []\n",
        "for l in loaders:\n",
        "    docs.extend(l.load())\n",
        "text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000)\n",
        "docs = text_splitter.split_documents(docs)"
      ],
      "metadata": {
        "id": "LcC3gnqXSZHs"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "vectorstore = Chroma(\n",
        "    collection_name=\"full_documents\",\n",
        "    embedding_function=OpenAIEmbeddings()\n",
        ")\n",
        "vectorstore.add_documents(docs)"
      ],
      "metadata": {
        "id": "8VoyrUwTShHw"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "#### 2. Set up a conversational retrieval QA chain by LangChain, based on the vector store."
      ],
      "metadata": {
        "id": "PxFsXiHVciOo"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "qa = ConversationalRetrievalChain.from_llm(\n",
        "    OpenAI(temperature=0),\n",
        "    vectorstore.as_retriever(),\n",
        "    memory=ConversationBufferMemory(memory_key=\"chat_history\", return_messages=True)\n",
        ")"
      ],
      "metadata": {
        "id": "6eRvVjJITKfR"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "result = qa(({\"question\": \"What is uniswap?\"}))"
      ],
      "metadata": {
        "id": "sXST-2kRTUOs"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "result['answer']"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 54
        },
        "id": "WVi6rT78Tsu_",
        "outputId": "d1808979-3d18-4847-c45a-0f3864bc8819"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'\\nUniswap is a decentralized cryptocurrency exchange that allows users to trade Ethereum-based tokens without the need for a centralized exchange. It is built on the Ethereum blockchain and uses automated market makers to facilitate trades.'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 32
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "#### 3. Define a function `answer_uniswap_question`\n",
        "\n",
        "It takes a parameter `question`, calls the QA chain, and answer it by returning the answer from the chain response."
      ],
      "metadata": {
        "id": "O7VPXVI_coX4"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def answer_uniswap_question(question):\n",
        "  response = qa({\"question\": question})\n",
        "  return response[\"answer\"]"
      ],
      "metadata": {
        "id": "yPThjcdFT1Lw"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "#### 4. Set up AutoGen user agent and assistant agent with function calling enabled."
      ],
      "metadata": {
        "id": "Wu7gjAv-c4uP"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ZsXuHf1fgkhl"
      },
      "outputs": [],
      "source": [
        "llm_config={\n",
        "    \"request_timeout\": 600,\n",
        "    \"seed\": 42,\n",
        "    \"config_list\": config_list,\n",
        "    \"temperature\": 0,\n",
        "    \"functions\": [\n",
        "        {\n",
        "            \"name\": \"answer_uniswap_question\",\n",
        "            \"description\": \"Answer any Uniswap related questions\",\n",
        "            \"parameters\": {\n",
        "                \"type\": \"object\",\n",
        "                \"properties\": {\n",
        "                    \"question\": {\n",
        "                        \"type\": \"string\",\n",
        "                        \"description\": \"The question to ask in relation to Uniswap protocol\",\n",
        "                    }\n",
        "                },\n",
        "                \"required\": [\"question\"],\n",
        "            },\n",
        "        }\n",
        "    ],\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "eg9g65hOgkhm"
      },
      "outputs": [],
      "source": [
        "# create an AssistantAgent instance named \"assistant\"\n",
        "assistant = autogen.AssistantAgent(\n",
        "    name=\"assistant\",\n",
        "    llm_config=llm_config,\n",
        ")\n",
        "# create a UserProxyAgent instance named \"user_proxy\"\n",
        "user_proxy = autogen.UserProxyAgent(\n",
        "    name=\"user_proxy\",\n",
        "    human_input_mode=\"NEVER\",\n",
        "    max_consecutive_auto_reply=10,\n",
        "    code_execution_config={\"work_dir\": \".\"},\n",
        "    llm_config=llm_config,\n",
        "    system_message=\"\"\"Reply TERMINATE if the task has been solved at full satisfaction.\n",
        "Otherwise, reply CONTINUE, or the reason why the task is not solved yet.\"\"\",\n",
        "    function_map={\"answer_uniswap_question\": answer_uniswap_question}\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### It's time to start a task for the agents.\n",
        "\n",
        "Now, let's user the user agent to ask the agents to write an introduction blog for `Uniswap` protocol v3."
      ],
      "metadata": {
        "id": "37cRtpqLdLSZ"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "aCdAqig3gkhn",
        "outputId": "0deb286b-a1e4-4b56-e8c4-4ab7ea33173f",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "user_proxy (to assistant):\n",
            "\n",
            "\n",
            "I'm writing a blog to introduce the version 3 of Uniswap protocol. Find the answers to the 3 questions below and write an introduction based on them.\n",
            "\n",
            "1. What is Uniswap?\n",
            "2. What are the main changes in Uniswap version 3?\n",
            "3. How to use Uniswap?\n",
            "\n",
            "Start the work now.\n",
            "\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "assistant (to user_proxy):\n",
            "\n",
            "***** Suggested function Call: answer_uniswap_question *****\n",
            "Arguments: \n",
            "\n",
            "{\n",
            "  \"question\": \"What is Uniswap?\"\n",
            "}\n",
            "************************************************************\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "\n",
            ">>>>>>>> EXECUTING FUNCTION answer_uniswap_question...\n",
            "user_proxy (to assistant):\n",
            "\n",
            "***** Response from calling function \"answer_uniswap_question\" *****\n",
            "\n",
            "Uniswap is a decentralized cryptocurrency exchange that allows users to trade Ethereum-based tokens without the need for a centralized exchange. It is built on the Ethereum blockchain and uses automated market makers to facilitate trades.\n",
            "********************************************************************\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "assistant (to user_proxy):\n",
            "\n",
            "***** Suggested function Call: answer_uniswap_question *****\n",
            "Arguments: \n",
            "\n",
            "{\n",
            "  \"question\": \"What are the main changes in Uniswap version 3?\"\n",
            "}\n",
            "************************************************************\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "\n",
            ">>>>>>>> EXECUTING FUNCTION answer_uniswap_question...\n",
            "user_proxy (to assistant):\n",
            "\n",
            "***** Response from calling function \"answer_uniswap_question\" *****\n",
            "\n",
            "\n",
            "Uniswap version 3 introduces a number of new features, including a new fee structure, improved liquidity provisioning, and a new liquidity mining program. It also includes a new user interface, improved gas efficiency, and a new governance system.\n",
            "********************************************************************\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "assistant (to user_proxy):\n",
            "\n",
            "***** Suggested function Call: answer_uniswap_question *****\n",
            "Arguments: \n",
            "\n",
            "{\n",
            "  \"question\": \"How to use Uniswap?\"\n",
            "}\n",
            "************************************************************\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "\n",
            ">>>>>>>> EXECUTING FUNCTION answer_uniswap_question...\n",
            "user_proxy (to assistant):\n",
            "\n",
            "***** Response from calling function \"answer_uniswap_question\" *****\n",
            "\n",
            "\n",
            "To use Uniswap, you will need to have a web3 wallet such as MetaMask installed and connected to the Ethereum network. Once you have your wallet set up, you can go to the Uniswap website and connect your wallet. From there, you can select the tokens you want to trade and execute the swap.\n",
            "********************************************************************\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "assistant (to user_proxy):\n",
            "\n",
            "Based on the answers to your questions, here is a draft introduction for your blog:\n",
            "\n",
            "Uniswap is a revolutionary decentralized cryptocurrency exchange that operates on the Ethereum blockchain. It allows users to trade Ethereum-based tokens directly from their wallets, bypassing the need for a centralized exchange. Uniswap uses automated market makers to facilitate trades, providing a seamless and efficient trading experience.\n",
            "\n",
            "The latest version, Uniswap version 3, brings a host of new features and improvements. It introduces a new fee structure, making transactions more cost-effective for users. The liquidity provisioning has been enhanced, allowing for more efficient use of capital. A new liquidity mining program has been introduced, providing incentives for users to provide liquidity to the platform. Additionally, Uniswap V3 boasts a new user interface, improved gas efficiency, and a revamped governance system, making it more user-friendly and democratic.\n",
            "\n",
            "Using Uniswap is straightforward. All you need is a web3 wallet, such as MetaMask, connected to the Ethereum network. Once your wallet is set up, you can visit the Uniswap website, connect your wallet, select the tokens you wish to trade, and execute the swap. It's as simple as that!\n",
            "\n",
            "Uniswap V3 is a significant step forward in the world of decentralized finance, providing users with more control, flexibility, and efficiency in their trading activities.\n",
            "\n",
            "TERMINATE\n",
            "\n",
            "--------------------------------------------------------------------------------\n",
            "user_proxy (to assistant):\n",
            "\n",
            "TERMINATE\n",
            "\n",
            "--------------------------------------------------------------------------------\n"
          ]
        }
      ],
      "source": [
        "# the assistant receives a message from the user, which contains the task description\n",
        "user_proxy.initiate_chat(\n",
        "    assistant,\n",
        "    message=\"\"\"\n",
        "I'm writing a blog to introduce the version 3 of Uniswap protocol. Find the answers to the 3 questions below and write an introduction based on them.\n",
        "\n",
        "1. What is Uniswap?\n",
        "2. What are the main changes in Uniswap version 3?\n",
        "3. How to use Uniswap?\n",
        "\n",
        "Start the work now.\n",
        "\"\"\"\n",
        ")"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.9.17"
    },
    "vscode": {
      "interpreter": {
        "hash": "949777d72b0d2535278d3dc13498b2535136f6dfe0678499012e853ee9abcab1"
      }
    },
    "colab": {
      "provenance": [],
      "include_colab_link": true
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}